package org.codefinger.dao.impl.oracle;

import java.util.List;

import org.codefinger.dao.impl.DataAccesser;
import org.codefinger.dao.impl.Querier;
import org.codefinger.dao.impl.QueryBuilder;
import org.codefinger.dao.impl.SQLVisitor;
import org.codefinger.dao.impl.sql.Column;
import org.codefinger.dao.impl.sql.ColumnItem;
import org.codefinger.dao.impl.sql.Group;
import org.codefinger.dao.impl.sql.GroupItem;
import org.codefinger.dao.impl.sql.IValue;
import org.codefinger.dao.impl.sql.IValueItem;
import org.codefinger.dao.impl.sql.Join;
import org.codefinger.dao.impl.sql.JoinItem;
import org.codefinger.dao.impl.sql.Order;
import org.codefinger.dao.impl.sql.OrderItem;
import org.codefinger.dao.impl.sql.UValueItem;
import org.codefinger.dao.impl.sql.Union;
import org.codefinger.dao.impl.sql.UnionItem;

public class OracleQueryBuilder extends QueryBuilder {

	public OracleQueryBuilder(DataAccesser dataAccesser) {
		super(dataAccesser);
	}

	public OracleQueryBuilder() {
		super();
	}

	public OracleQueryBuilder(List<UValueItem> uValues) {
		super(uValues);
	}

	public OracleQueryBuilder(DataAccesser dataAccesser, String table) {
		super(dataAccesser, table);
	}

	@Override
	public Querier buildQuerier() {
		return new OracleQuerier(dataAccesser.getDataSource(),//
				isDistinct, new Column(columns.toArray(new ColumnItem[columns.size()])),//
				from, //
				joins == null ? null : new Join(joins.toArray(new JoinItem[joins.size()])),//
				where,//
				groups == null ? null : new Group(groups.toArray(new GroupItem[groups.size()])),//
				having, unions == null ? null : new Union(unions.toArray(new UnionItem[unions.size()])),//
				orders == null ? null : new Order(orders.toArray(new OrderItem[orders.size()])),//
				aliases.toArray(new String[aliases.size()]));
	}

	@Override
	public IValue buildIValue() {
		final int size = iValues.size();
		final IValueItem[] items = iValues.toArray(new IValueItem[size]);
		String table = this.table;
		StringBuilder sqlBuilder = new StringBuilder("INSERT INTO ").append(table).append('(').append(subQueryAlias);
		for (IValueItem item : items) {
			sqlBuilder.append(',').append(item.getName());
		}
		sqlBuilder.append(") VALUES (").append("SEQ$").append(table).append(".NEXTVAL");
		final String preffix = sqlBuilder.toString();
		return new IValue() {

			@Override
			public void visit(SQLVisitor visitor) {
				visitor.appendSQL(preffix);
				for (IValueItem item : items) {
					visitor.appendSQL(',');
					item.visitExp(visitor);
				}
				visitor.appendSQL(')');
			}
		};
	}
}
